/**
 * 股票选择器核心功能模块
 * 负责处理股票筛选、排序和评分等核心功能
 */
class StockSelectorCore {
    constructor(config = {}) {
        this.config = {
            weightConfig: {
                technical: 0.3,    // 技术面权重
                fundamental: 0.3,  // 基本面权重
                sentiment: 0.2,    // 情绪面权重
                industry: 0.2      // 行业面权重
            },
            scoreThresholds: {
                excellent: 80,     // 优秀阈值
                good: 60,          // 良好阈值
                fair: 40          // 一般阈值
            },
            ...config
        };

        // 缓存管理
        this.cache = new Map();
        this.cacheTimeout = 5 * 60 * 1000; // 5分钟缓存
    }

    /**
     * 应用筛选条件
     * @param {Array} stocks 股票数据
     * @param {Object} filters 筛选条件
     * @returns {Array} 筛选后的股票列表
     */
    applyFilters(stocks, filters) {
        return stocks.filter(stock => {
            // 行业筛选
            if (filters.industries?.length > 0 && !filters.industries.includes(stock.industry)) {
                return false;
            }

            // 市值范围筛选
            const marketCap = stock.marketCap;
            if (filters.marketCapMin && marketCap < filters.marketCapMin) {
                return false;
            }
            if (filters.marketCapMax && marketCap > filters.marketCapMax) {
                return false;
            }

            // AI评分筛选
            if (filters.aiScoreMin && stock.aiScore < filters.aiScoreMin) {
                return false;
            }

            // 技术指标筛选
            if (!this.checkTechnicalIndicators(stock, filters)) {
                return false;
            }

            // 基本面指标筛选
            if (!this.checkFundamentalIndicators(stock, filters)) {
                return false;
            }

            return true;
        });
    }

    /**
     * 检查技术指标
     * @param {Object} stock 股票数据
     * @param {Object} filters 筛选条件
     * @returns {boolean} 是否满足条件
     */
    checkTechnicalIndicators(stock, filters) {
        // MACD指标
        if (filters.macd) {
            const macdResult = this.calculateMACD(stock.prices);
            if (filters.macd === 'up' && macdResult.signal <= 0) {
                return false;
            }
            if (filters.macd === 'down' && macdResult.signal >= 0) {
                return false;
            }
        }

        // KDJ指标
        if (filters.kdj) {
            const kdjResult = this.calculateKDJ(stock.prices);
            if (filters.kdj === 'up' && kdjResult.j <= kdjResult.k) {
                return false;
            }
            if (filters.kdj === 'down' && kdjResult.j >= kdjResult.k) {
                return false;
            }
        }

        // RSI指标
        if (filters.rsi) {
            const rsi = this.calculateRSI(stock.prices);
            if (filters.rsi === 'overbought' && rsi < 70) {
                return false;
            }
            if (filters.rsi === 'oversold' && rsi > 30) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查基本面指标
     * @param {Object} stock 股票数据
     * @param {Object} filters 筛选条件
     * @returns {boolean} 是否满足条件
     */
    checkFundamentalIndicators(stock, filters) {
        // 市盈率(PE)
        if (filters.peMin && stock.pe < filters.peMin) return false;
        if (filters.peMax && stock.pe > filters.peMax) return false;

        // 市净率(PB)
        if (filters.pbMin && stock.pb < filters.pbMin) return false;
        if (filters.pbMax && stock.pb > filters.pbMax) return false;

        // 股息率
        if (filters.dividendMin && stock.dividend < filters.dividendMin) return false;
        if (filters.dividendMax && stock.dividend > filters.dividendMax) return false;

        // 营收增长率
        if (filters.revenueGrowthMin && stock.revenueGrowth < filters.revenueGrowthMin) return false;
        if (filters.revenueGrowthMax && stock.revenueGrowth > filters.revenueGrowthMax) return false;

        return true;
    }

    /**
     * 计算综合评分
     * @param {Object} stock 股票数据
     * @returns {number} 综合评分
     */
    calculateScore(stock) {
        const scores = {
            technical: this.calculateTechnicalScore(stock),
            fundamental: this.calculateFundamentalScore(stock),
            sentiment: this.calculateSentimentScore(stock),
            industry: this.calculateIndustryScore(stock)
        };

        // 加权计算最终得分
        let finalScore = 0;
        Object.entries(scores).forEach(([key, score]) => {
            finalScore += score * this.config.weightConfig[key];
        });

        return Math.round(finalScore * 100) / 100;
    }

    /**
     * 计算技术面得分
     * @param {Object} stock 股票数据
     * @returns {number} 技术面得分
     */
    calculateTechnicalScore(stock) {
        let score = 0;
        const prices = stock.prices || [];

        // MACD信号
        const macd = this.calculateMACD(prices);
        score += macd.signal > 0 ? 0.3 : 0;

        // KDJ指标
        const kdj = this.calculateKDJ(prices);
        score += (kdj.j > kdj.k) ? 0.3 : 0;

        // RSI指标
        const rsi = this.calculateRSI(prices);
        if (rsi < 30) score += 0.2; // 超卖
        if (rsi > 70) score -= 0.2; // 超买

        // 均线系统
        const ma = this.calculateMA(prices);
        if (ma.ma5 > ma.ma10) score += 0.1;
        if (ma.ma10 > ma.ma20) score += 0.1;

        return Math.max(0, Math.min(1, score));
    }

    /**
     * 计算基本面得分
     * @param {Object} stock 股票数据
     * @returns {number} 基本面得分
     */
    calculateFundamentalScore(stock) {
        let score = 0;

        // PE估值
        const peScore = this.calculatePEScore(stock.pe, stock.industry);
        score += peScore * 0.3;

        // PB估值
        const pbScore = this.calculatePBScore(stock.pb, stock.industry);
        score += pbScore * 0.2;

        // 营收增长
        if (stock.revenueGrowth > 0) {
            score += Math.min(stock.revenueGrowth / 30, 1) * 0.25;
        }

        // 净利润增长
        if (stock.profitGrowth > 0) {
            score += Math.min(stock.profitGrowth / 30, 1) * 0.25;
        }

        return Math.max(0, Math.min(1, score));
    }

    /**
     * 计算情绪面得分
     * @param {Object} stock 股票数据
     * @returns {number} 情绪面得分
     */
    calculateSentimentScore(stock) {
        let score = 0;

        // 资金流向
        if (stock.moneyFlow > 0) {
            score += Math.min(stock.moneyFlow / 100000000, 0.4);
        }

        // 成交量变化
        if (stock.volumeRatio > 1) {
            score += Math.min((stock.volumeRatio - 1) / 2, 0.3);
        }

        // 机构持仓
        if (stock.institutionalHolding > 0) {
            score += Math.min(stock.institutionalHolding / 50, 0.3);
        }

        return Math.max(0, Math.min(1, score));
    }

    /**
     * 计算行业面得分
     * @param {Object} stock 股票数据
     * @returns {number} 行业面得分
     */
    calculateIndustryScore(stock) {
        let score = 0;

        // 行业景气度
        if (stock.industryProsperity > 0) {
            score += Math.min(stock.industryProsperity / 100, 0.4);
        }

        // 行业排名
        if (stock.industryRank > 0) {
            score += Math.min((100 - stock.industryRank) / 100, 0.3);
        }

        // 行业集中度
        if (stock.industryConcentration > 0) {
            score += Math.min(stock.industryConcentration / 100, 0.3);
        }

        return Math.max(0, Math.min(1, score));
    }

    /**
     * 计算PE得分
     * @param {number} pe PE值
     * @param {string} industry 行业
     * @returns {number} PE得分
     */
    calculatePEScore(pe, industry) {
        // 从缓存获取行业PE
        const industryPE = this.getIndustryPE(industry);
        if (!pe || !industryPE) return 0;

        const ratio = pe / industryPE;
        if (ratio <= 0.5) return 1;
        if (ratio <= 0.8) return 0.8;
        if (ratio <= 1.2) return 0.6;
        if (ratio <= 1.5) return 0.4;
        return 0.2;
    }

    /**
     * 计算PB得分
     * @param {number} pb PB值
     * @param {string} industry 行业
     * @returns {number} PB得分
     */
    calculatePBScore(pb, industry) {
        // 从缓存获取行业PB
        const industryPB = this.getIndustryPB(industry);
        if (!pb || !industryPB) return 0;

        const ratio = pb / industryPB;
        if (ratio <= 0.5) return 1;
        if (ratio <= 0.8) return 0.8;
        if (ratio <= 1.2) return 0.6;
        if (ratio <= 1.5) return 0.4;
        return 0.2;
    }

    /**
     * 获取行业PE
     * @param {string} industry 行业
     * @returns {number} 行业PE
     */
    getIndustryPE(industry) {
        const cacheKey = `industry_pe_${industry}`;
        const cached = this.cache.get(cacheKey);
        
        if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
            return cached.value;
        }

        // TODO: 从服务器获取行业PE
        const industryPE = 15; // 临时固定值
        
        this.cache.set(cacheKey, {
            value: industryPE,
            timestamp: Date.now()
        });

        return industryPE;
    }

    /**
     * 获取行业PB
     * @param {string} industry 行业
     * @returns {number} 行业PB
     */
    getIndustryPB(industry) {
        const cacheKey = `industry_pb_${industry}`;
        const cached = this.cache.get(cacheKey);
        
        if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
            return cached.value;
        }

        // TODO: 从服务器获取行业PB
        const industryPB = 2; // 临时固定值
        
        this.cache.set(cacheKey, {
            value: industryPB,
            timestamp: Date.now()
        });

        return industryPB;
    }

    /**
     * 计算MACD指标
     * @param {Array} prices 价格数据
     * @returns {Object} MACD计算结果
     */
    calculateMACD(prices) {
        if (!prices || prices.length < 26) {
            return { dif: 0, dea: 0, macd: 0, signal: 0 };
        }

        // 计算快速和慢速EMA
        const fastEMA = this.calculateEMA(prices, 12);
        const slowEMA = this.calculateEMA(prices, 26);

        // 计算DIF
        const dif = fastEMA - slowEMA;

        // 计算DEA
        const dea = this.calculateEMA([dif], 9);

        // 计算MACD
        const macd = 2 * (dif - dea);

        return {
            dif,
            dea,
            macd,
            signal: macd > 0 ? 1 : -1
        };
    }

    /**
     * 计算KDJ指标
     * @param {Array} prices 价格数据
     * @returns {Object} KDJ计算结果
     */
    calculateKDJ(prices) {
        if (!prices || prices.length < 9) {
            return { k: 50, d: 50, j: 50 };
        }

        // 计算RSV
        const rsv = this.calculateRSV(prices, 9);

        // 计算K值
        const k = this.calculateSMA(rsv, 3);

        // 计算D值
        const d = this.calculateSMA([k], 3);

        // 计算J值
        const j = 3 * k - 2 * d;

        return { k, d, j };
    }

    /**
     * 计算RSI指标
     * @param {Array} prices 价格数据
     * @returns {number} RSI值
     */
    calculateRSI(prices) {
        if (!prices || prices.length < 14) {
            return 50;
        }

        let gains = 0;
        let losses = 0;

        // 计算14天的涨跌
        for (let i = 1; i < 15; i++) {
            const change = prices[i] - prices[i - 1];
            if (change >= 0) {
                gains += change;
            } else {
                losses -= change;
            }
        }

        // 计算RSI
        const rs = gains / losses;
        const rsi = 100 - (100 / (1 + rs));

        return rsi;
    }

    /**
     * 计算移动平均线
     * @param {Array} prices 价格数据
     * @returns {Object} 移动平均线计算结果
     */
    calculateMA(prices) {
        return {
            ma5: this.calculateSMA(prices, 5),
            ma10: this.calculateSMA(prices, 10),
            ma20: this.calculateSMA(prices, 20)
        };
    }

    /**
     * 计算EMA
     * @param {Array} data 数据
     * @param {number} period 周期
     * @returns {number} EMA值
     */
    calculateEMA(data, period) {
        const k = 2 / (period + 1);
        let ema = data[0];
        
        for (let i = 1; i < data.length; i++) {
            ema = (data[i] * k) + (ema * (1 - k));
        }
        
        return ema;
    }

    /**
     * 计算SMA
     * @param {Array} data 数据
     * @param {number} period 周期
     * @returns {number} SMA值
     */
    calculateSMA(data, period) {
        if (data.length < period) {
            return data.reduce((a, b) => a + b, 0) / data.length;
        }

        let sum = 0;
        for (let i = 0; i < period; i++) {
            sum += data[i];
        }
        
        return sum / period;
    }

    /**
     * 计算RSV
     * @param {Array} prices 价格数据
     * @param {number} period 周期
     * @returns {number} RSV值
     */
    calculateRSV(prices, period) {
        if (prices.length < period) {
            return 50;
        }

        const periodPrices = prices.slice(0, period);
        const high = Math.max(...periodPrices);
        const low = Math.min(...periodPrices);
        const close = prices[0];

        return ((close - low) / (high - low)) * 100;
    }
}

// 导出为全局变量
window.StockSelectorCore = StockSelectorCore;